import { AppTask } from "../../app.task.class";
import { logger } from "../../../configs/log.config";
import { timer } from "rxjs";
import mqtt from "mqtt";

/**
 * 告警消息推送
 */
export class SrAlertMqttPublishTask extends AppTask {
  /**
   * 构造函数
   * @param __mqttClient
   * @param __topic
   * @param __payload
   */
  constructor(
    private __mqttClient: mqtt.MqttClient,
    private __topic: string,
    private __payload: string | Buffer,
  ) {
    super();
  }

  __pause(): Promise<boolean> {
    return Promise.resolve(false);
  }

  __restore(): Promise<boolean> {
    return Promise.resolve(false);
  }

  /**
   * 运行
   * 1. 发送消息, 如果失败则重试
   */
  async __run(): Promise<void> {
    try {
      await new Promise(this.__publishToMQTT.bind(this));
    } catch (e) {
      logger.error("mqtt 发送失败： topic: %s", this.__topic, e);
    }
  }

  /**
   * 发送 mqtt 消息
   * 1. 默认 重试 2 次；
   * @param resolve
   * @param reject
   * @param retry
   * @private
   */
  private async __publishToMQTT(resolve: any, reject: any, retry = 2) {
    if (this.isStopped()) return resolve();
    if (!this.__mqttClient) return reject("mqtt 客户端尚未连接");
    if (this.__mqttClient.disconnected) return reject("mqtt 已断开");
    this.__mqttClient.publish(
      this.__topic,
      this.__payload,
      { qos: 0, retain: true },
      (error: Error | undefined) => {
        if (!error) {
          logger.info("mqtt send success , topic %s", this.__topic);
          return resolve();
        }
        if (retry < 1) {
          return reject(error);
        }
        logger.error("mqtt 发送失败： topic: %s, 剩余重试: %d ", this.__topic, retry, error);
        timer(3000).subscribe(() => {
          this.__publishToMQTT(resolve, reject, retry - 1);
        });
      },
    );
  }

  __stop(): Promise<boolean> {
    return Promise.resolve(false);
  }
}
